import random
import time
from django.conf import settings
from django.core.cache import caches
from django.http import HttpResponse
from django.middleware.http import MiddlewareMixin
from django.shortcuts import reverse
from utils.response import response, RET


class PostAuthenticateMiddleware(MiddlewareMixin):
    def process_request(self, request):
        """
        ajax post请求必须先登录
        :param request:
        :return:
        """
        if request.is_ajax() and request.method == 'POST':
            if not request.user.is_authenticated:
                return response(RET.SESSIONERR)
        return None

    # def process_view(self, request, view_func, view_args, view_kwargs):
    #     pass
    #
    # def process_exception(self, request, exception):
    #     pass
    #
    # def process_response(self, request, response):
    #     pass


class SearchThrottleMiddleware(MiddlewareMixin):
    def get_ident(self, request):

        xff = request.META.get('HTTP_X_FORWARDED_FOR')
        remote_addr = request.META.get('REMOTE_ADDR')

        return ''.join(xff.split()) if xff else remote_addr

    def parse_rate(self):
        num, period = settings.SEARCH_THROTTLE.split('/')  # 解析时间
        num_requests = int(num)  # 转换数字
        duration = {'s': 1, 'm': 60, 'h': 3600, 'd': 86400}[period[0]]
        return num_requests, duration

    @property
    def cache(self):
        return caches['search']

    def process_request(self, request):
        """
        搜索节流
        :param request:
        :return:
        """
        if request.path == reverse('blog:search'):
            # 请求 ip
            key = self.get_ident(request)
            # 频率
            num_requests, duration = self.parse_rate()
            # 拿到当前时间
            now = time.time()
            # 历史数据
            history = self.cache.get(key, [])
            # 去除过期数据
            while history and history[-1] <= now - duration:
                history.pop()
            # 大于频率
            if len(history) >= num_requests:
                return HttpResponse('请求过快')
            # 小于频率 或 没有
            history.insert(0, now)
            self.cache.set(key, history)
        return None
